﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.Hosting;
using Medianamik.Core.Logging;

namespace Medianamik.Core.Urls
{
    public class UrlRewriter : IHttpModule
    {
        private static ILogger _logger = new ObjectFactory<ILogger>().Get("UrlRewriterLogger");

        public virtual IUrlDictionary Urls
        {
            get
            {
                return new ObjectFactory<IUrlDictionary>().Get();

            }
        }

        public virtual IUrlDictionaryProcess UrlProcess
        {
            get
            {
                return new ObjectFactory<IUrlDictionaryProcess>().Get();

            }
        }

        public void Dispose()
        {
            ;
        }

        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(context_BeginRequest);

        }

        protected virtual void context_BeginRequest(object sender, EventArgs e)
        {
            var app = (HttpApplication)sender;
            var url = GetUrl(app);
            var qs = GetQueryString(app);

            Rewrite(app, url, qs);
        }

        protected virtual string GetQueryString(HttpApplication app)
        {
            return app.Request.Url.Query;
        }

        protected virtual string GetUrl(HttpApplication app)
        {
            return app.Request.Url.GetLeftPart(UriPartial.Path);
        }

        private void Rewrite(HttpApplication app, string url, string qs)
        {
            try
            {
                Uri urlUri = new Uri(url);

                if (UrlProcess.ThisUrlIs404PageWhitoutTemplate(new Uri(string.Concat(url, qs))))
                {
                    app.Response.Write(string.Format("<html><body>404 error: {0}</body></html>", urlUri.ToString()));
                    app.Response.StatusCode = 404;
                    return;
                }

                if (UrlProcess.ThisUrlMustBeProcessWithDictionnary(urlUri))
                {

                    var entry = Urls.GetEntry(url);

                    if (entry == null)
                    {
                        HandleUnknownUrl(app, url, qs);
                    }
                    else
                    {
                        Rewrite(url, app, entry, qs);
                    }
                }
            }
            catch (Exception exc)
            {
                //Le site est mort !!
                _logger.Fatal("Erreur dans le module d'Url Rewriting", exc);
            }
        }

        protected virtual void Rewrite(string url, HttpApplication app, IUrlDictionaryEntry entry, string qs)
        {
            app.Context.RewritePath(entry.RewritedPath + qs);
            app.Context.Items["RewritedUrlCultureName"] = entry.Culture.Name;
            app.Context.Items["RewritedUrlId"] = entry.NodeId;
            app.Context.Items["Medianamik-Rewrite-Url"] = entry.RequestedPath; /*GetFileName(app, url, entry);*/
        }

        protected virtual void HandleUnknownUrl(HttpApplication application, string url, string qs)
        {

        }

        protected virtual string GetFileName(HttpApplication app, string url, IUrlDictionaryEntry entry)
        {
            var fileName = Path.GetFileName(url);

            if (String.IsNullOrEmpty(fileName))
            {
                fileName = Path.GetFileName(Urls.GetEntries(entry.NodeId, entry.Culture).Where(u =>
                    app.Request.Url.Authority.Equals(u.Domain, StringComparison.InvariantCultureIgnoreCase))
                    .Select(u => u.RequestedUrl).FirstOrDefault().ToString());
            }

            return fileName;
        }
    }
}
